package edu.whu.irlab.woscrawl.selenium;

import edu.whu.irlab.woscrawl.util.Constants;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Set;

/**
 * Created by zhongwei on 16/5/20.
 */
public class Worker extends Thread {

    private int start;
    private int end;
    private String firefoxPath;
    private String savePath;
    private File folder;
    private WebDriver driver;
    private String prefix;
    private Set<Integer> set;

    public Worker(int start, int end, String firefoxPath, String savePath, String name, Set set) {
        this.start = start;
        this.end = end;
        this.firefoxPath = firefoxPath;
        this.savePath = savePath;
        this.set = set;
        folder = new File(savePath);
        setName(name);
    }
    void login() throws InterruptedException {
        driver = new FirefoxDriver(new FirefoxBinary(new File(firefoxPath)), new FirefoxProfile());
        driver.get(Constants.LIB_ENTRY_URL);
        sleep();
        WebElement input = driver.findElement(By.id("value(input1)"));
        input.clear();
        input.sendKeys("china");
        WebElement addButton = driver.findElement(By.id("addSearchRow1")).findElements(By.tagName("span")).get(0);
        addButton.click();
        driver.findElement(By.id("value(bool_1_2)")).findElements(By.tagName("option")).get(1).click();
        // AND
        WebElement input2 = driver.findElement(By.id("value(input2)"));
        input2.clear();
        input2.sendKeys("chinese");
        addButton = driver.findElement(By.id("addSearchRow2")).findElements(By.tagName("span")).get(0);
        addButton.click();
        // NOT
        driver.findElement(By.id("value(bool_2_3)")).findElements(By.tagName("option")).get(2).click();
        WebElement input3 = driver.findElement(By.id("value(input3)"));
        input3.clear();
        input3.sendKeys("china");
        // OG
        driver.findElement(By.id("select3")).findElement(By.id("OG_search_field")).click();
        // Search
        driver.findElement(By.id("searchCell3")).click();
        sleep();
        WebElement firstR = driver.findElements(By.className("search-results-item")).get(0);
        firstR.findElement(By.className("smallV110")).click();
        String current = driver.getCurrentUrl();
        prefix = current.replace("&page=1&doc=1", "&doc=");
    }
    void retry(int start, int end) throws InterruptedException, IOException {
        login();
        doStaff(start, end);
    }

    void sleep() throws InterruptedException {
        Thread.currentThread().sleep(Constants.SLEEP_SECONDS);
    }

    public void doStaff(int start, int end) throws InterruptedException, IOException {
        login();
        for (int i = start; i <= end; i++) {
            if (set.contains(i)) continue;
            driver.get(prefix + i);
            try {
                sleep();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String page = driver.getPageSource();
            if (!page.contains(Constants.PREREQUISITE_MESSAGE)) {
                System.err.println(getName() + " session失效,重新登录中...");
                driver.close();
                retry(i, end);
            }
            FileWriter fileWriter = new FileWriter(new File(folder, String.valueOf(i) + ".txt"));
            Document document = Jsoup.parse(driver.getPageSource());
            fileWriter.append(document.getElementsByClass("l-content").html());
            fileWriter.flush();
            fileWriter.close();
            System.out.println(getName() + " get num " + i + " done!");
            sleep(Constants.SLEEP_PER_REQ);
        }
        driver.close();
    }
    @Override
    public void run() {
        try {
            doStaff(start, end);
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.exit(-1);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}
